namespace WP7Contrib.Services.BingMaps.Model
{
    using System;
    using System.Device.Location;
    using System.Windows;
    using Microsoft.Phone.Controls.Maps;
    using Collections;
    using Common;

    public class ImagerySearchCriterion : BaseModel, ICriterion<ImagerySearchCriterion>,
                                                     IImageryUrlForCenterPointCriterion,
                                                     IImageryUrlForCenterPointWithRouteCriterion,
                                                     IImageryUrlForRouteCriterion,
                                                     IImageryUrlForQueryCriterion,
                                                     IImageryUrForSpecificAreaCriterion,
                                                     IImageryUrForSpecificAreaWithRouteCriterion
    {
        private Avoid avoid;
        private GeoCoordinate centerPoint;
        private DateTime? dateTime;
        private ImagerySet imagerySet;
        private LocationRect mapArea;
        private MapLayer? mapLayer;
        private int? maxSolutions;
        private Size? mapSize;
        private Optimize? optimize;
        private string query;
        private TimeType? timeType;
        private ModeOfTravel? travelMode;
        private int? zoomLevel;
        private MapVersion? mapVersion;

        private ObservableCollection<PushPin> pushPins;
        private ObservableCollection<WayPoint> waypoints;

        public ImagerySearchCriterion()
        {
            this.Reset();
        }

        public Avoid Avoid
        {
            get
            {
                return this.avoid;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.avoid, value, () => this.Avoid);
            }
        }

        public GeoCoordinate CenterPoint
        {
            get
            {
                return this.centerPoint;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.centerPoint, value, () => this.CenterPoint);
            }
        }

        public int? ZoomLevel
        {
            get
            {
                return this.zoomLevel;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.zoomLevel, value, () => this.ZoomLevel);
            }
        }

        public Size? MapSize
        {
            get
            {
                return this.mapSize;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.mapSize, value, () => this.MapSize);
            }
        }

        public ObservableCollection<PushPin> PushPins
        {
            get
            {
                return this.pushPins;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.pushPins, value, () => this.PushPins);
            }
        }

        public ImagerySet ImagerySet
        {
            get
            {
                return this.imagerySet;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.imagerySet, value, () => this.ImagerySet);
            }
        }

        public DateTime? DateTime
        {
            get
            {
                return this.dateTime;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.dateTime, value, () => this.DateTime);
            }
        }

        public LocationRect MapArea
        {
            get
            {
                return this.mapArea;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.mapArea, value, () => this.mapArea);
            }
        }

        public Model.MapLayer? MapLayer
        {
            get
            {
                return this.mapLayer;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.mapLayer, value, () => this.MapLayer);
            }
        }

        public MapVersion? MapVersion
        {
            get
            {
                return this.mapVersion;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.mapVersion, value, () => this.MapVersion);
            }
        }

        public int? MaxSolutions
        {
            get
            {
                return this.maxSolutions;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.maxSolutions, value, () => this.MaxSolutions);
            }
        }

        public Optimize? Optimize
        {
            get
            {
                return this.optimize;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.optimize, value, () => this.Optimize);
            }
        }

        public string Query
        {
            get
            {
                return this.query;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.query, value, () => this.Query);
            }
        }

        public TimeType? TimeType
        {
            get
            {
                return this.timeType;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.timeType, value, () => this.TimeType);
            }
        }

        public ModeOfTravel? TravelMode
        {
            get
            {
                return this.travelMode;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.travelMode, value, () => this.TravelMode);
            }
        }

        public ObservableCollection<WayPoint> WayPoints
        {
            get
            {
                return this.waypoints;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.waypoints, value, () => this.WayPoints);
            }
        }

        public ImagerySearchCriterion Reset()
        {
            this.avoid = new Avoid();
            this.centerPoint = new GeoCoordinate();
            this.imagerySet = ImagerySet.Road;
            this.mapArea = new LocationRect();
            this.mapLayer = Model.MapLayer.TrafficFlow;
            this.mapVersion = Model.MapVersion.V1;
            this.mapSize = new Size();
            this.maxSolutions = 1;
            this.optimize = Model.Optimize.Time;
            this.pushPins = new ObservableCollection<PushPin>();
            this.query = null;
            this.timeType = Model.TimeType.Departure;
            this.travelMode = ModeOfTravel.Driving;
            this.waypoints = new ObservableCollection<WayPoint>();
            
            return this;
        }
    }
}